package com.xteam.ecsystem.dao;

import java.io.Serializable;
import java.math.BigInteger;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import org.hibernate.HibernateException;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Order;

import com.xteam.ecsystem.utils.PageCenterStation;

/**
 * 数据访问基类，继承自分页接口 BasePageDao
 * 
 * @author hasee
 *
 */
@SuppressWarnings("unchecked")
public interface BaseDao<T> extends BasePageDao<T> {
	
	public List<Object> queryHqlIn(String hql,List listin);
	 
	
	public List<Object> queryHqlLis( final String hql, final Object[] args);

	/**
	 * 按指定查询的排序集 查询指定对象的所有数据
	 * 
	 * @param <T>
	 * @param clazz
	 *            指定对象类型
	 * @param orders
	 *            排序集
	 * @return
	 * @author yuanjie.wu
	 */
	public List<T> findAllByOrders(Class<T> clazz, Order[] orders)
			throws HibernateException;

	/**
	 * 按指定查询的条件集 查询指定对象的所有数据
	 * 
	 * @param <T>
	 * @param clazz
	 *            指定对象类型
	 * @param criterions
	 *            条件集
	 * @return
	 * @author yuanjie.wu
	 */
	public List<T> findAllByCriterions(Class<T> clazz,
			Criterion[] criterions) throws HibernateException;

	/**
	 * 按指定查询的条件集和排序集 查询指定对象的所有数据
	 * 
	 * @param <T>
	 * @param clazz
	 *            指定对象类型
	 * @param criterions
	 *            条件集
	 * @param orders
	 *            排序集
	 * @return
	 * @author yuanjie.wu
	 */
	public List<T> findAllByCriteronsAndOrders(Class<T> clazz,
			Criterion[] criterions, Order[] orders) throws HibernateException;

	/**
	 * 保存一个对象,返回该对象的主键
	 */
	public Serializable saveForReturn(Object obj) throws HibernateException,
			Exception;

	/**
	 * 批量保存对象
	 * 
	 * @param objects
	 *            对象集合
	 * @throws HibernateException
	 * @author yuanjie.wu
	 */
	public void batchSave(Collection<Object> objects) throws HibernateException;

	/**
	 * 批量保存对象
	 * 
	 * @param objects
	 *            对象数组
	 * @throws HibernateException
	 * @author yuanjie.wu
	 */
	public void batchSave(Object[] objects) throws HibernateException;
	
	/**
	 * 批量更新对象
	 * 
	 * @param objects
	 *            对象数组
	 * @throws HibernateException
	 * @author yuanjie.wu
	 */
	public void batchUpdate(Object[] objects) throws HibernateException;

	/**
	 * 保存或者更新一个对象
	 * 
	 * @param obj
	 * @throws HibernateException
	 */
	public void saveOrUpdate(Object obj) throws HibernateException;
	
	/**
	 * 
	 * 保存一个对象
	 * @author hasee
	 * @param obj
	 */
	public void save(Object obj);
	
	/**
	 * 
	 * 更新一个对象
	 * @author hasee
	 * @param obj
	 */
	public void update(Object obj);

	/**
	 * 删除一个对象
	 * 
	 * @param obj
	 * @throws HibernateException
	 */
	public void delete(Object obj) throws HibernateException;

	/**
	 * 根据ID和类Class获得一个对象
	 * 
	 * @param 要获得的类Class
	 * @param id
	 * @throws HibernateException
	 */
	public Object get(Class<?> classz, Serializable pk)
			throws HibernateException;

	/**
	 * 根据传入的查询条件，获得一个List结果集
	 * 
	 * @param hql
	 *            HQL查询语句
	 * @throws HibernateException
	 */
	public List<?> find(String hql) throws HibernateException;

	/**
	 * 一个查询方法 eg:from User where username=?
	 * 
	 * @param hql
	 *            HQL查询语句
	 * @param value
	 *            查询条件
	 * @return
	 * @throws HibernateException
	 */
	public List<?> find(String hql, Object param) throws HibernateException;

	/**
	 * 一个查询方法 eg:from User where username=? and password=?
	 * 
	 * @param hql
	 *            HQL查询语句
	 * @param values
	 *            查询条件数组
	 * @return @
	 */
	public List<?> find(String hql, Object[] params) throws HibernateException;

	/**
	 * 查询一个对象 eg:from User where username=? and password=?
	 * 
	 * @param hql
	 *            HQL查询语句
	 * @param params
	 *            查询条件数组
	 * @return
	 * @throws HibernateException
	 */
	public Object findObject(String hql, Object[] params)
			throws HibernateException;

	/**
	 * 根据传入的属性名和值，返回一个List
	 * 
	 * @param HQL查询语句
	 * @param 属性名
	 * @param 属性值
	 */
	public List<?> findByProperty(String hql, String propertyName, Object value)
			throws HibernateException;

	/**
	 * 根据传入一个Collection,删除这个Collection对象，即批量删除
	 * 
	 * @param c
	 * @throws HibernateException
	 */
	public void deleteAll(Collection<?> c) throws HibernateException;

	/**
	 * 根据传入一个Collection,保存这个Collection对象，即批量增加或者更新
	 * 
	 * @param c
	 * @throws HibernateException
	 */
	public void saveOrUpdateAll(Collection<?> c) throws HibernateException;

	/**
	 * 执行HQL查询方法
	 * 
	 * @param hql
	 * @param paramNames
	 *            HQL占位字符串
	 * @param values
	 *            HQL值数组
	 * @return @
	 */
	public List<?> query(String hql, String[] paramNames, Object[] values)
			throws HibernateException;

	/**
	 * 执行SQL查询方法
	 * 
	 * @param <T>
	 *            (Map, List, javaBean对象)
	 * @param clazz
	 *            返回类型
	 * @param sql
	 *            SQL查询语句
	 * @param params
	 *            SQL占位字符串数组
	 * @param values
	 *            SQL值数组
	 * @return
	 * @throws HibernateException
	 * @author yuanjie.wu
	 */
	public List<T> queryWithSQL(Class<T> clazz, String sql,
			String[] params, Object[] values) throws HibernateException;

	/**
	 * 返回最大记录数 <br>
	 * eg:select count(*) from User
	 * 
	 * @param hql
	 *            HQL查询语句
	 * @return
	 * @throws HibernateException
	 */
	public Long count(String hql) throws HibernateException;

	/**
	 * 返回最大记录数 <br>
	 * eg:select count(*) from User where username=? and password=?
	 * 
	 * @param hql
	 *            HQL查询语句
	 * @param args
	 *            HQL值数组
	 * @return
	 * @throws HibernateException
	 */
	public Long count(String hql, Object[] args) throws HibernateException;

	/**
	 * 执行SQL语句返回最大记录数
	 * 
	 * @param sql
	 *            SQL语句
	 * @param objs
	 *            SQL值数组
	 * @return
	 * @throws HibernateException
	 * @author yuanjie.wu
	 */
	public Long countWithSQL(String sql, Object... objs)
			throws HibernateException;

	/**
	 * 执行SQL语句返回最大记录数
	 * 
	 * @param sql
	 *            SQL语句
	 * @param params
	 *            SQL占位符数组
	 * @param objs
	 *            SQL值数组
	 * @return
	 * @throws HibernateException
	 * @author yuanjie.wu
	 */
	public Long countWithSQL(String sql, String[] params, Object[] objs)
			throws HibernateException;
	
	/**
	 * 执行SQL语句返回最大记录数（支持聚合函数）
	 * @author liuzhi Nov 19, 2013
	 * @param sql
	 * @param objs 参数值
	 * @return 返回BigInteger类型的值
	 * @throws HibernateException
	 */
	public BigInteger countWithAggFunSQL(String sql, Object[] objs)
			throws HibernateException;
	
	/**
	 * 
	 * 执行SQL语句返回最大记录数（支持复杂的SQL语句，返回Object类型的值）
	 * @author liuzhi Nov 19, 2013
	 * @param sql
	 * @param params 参数名
	 * @param objs  参数值
	 * @return 返回Object类型的值
	 * @throws HibernateException
	 */
	public Object countWithSQLForObjVal(final String sql, final String[] params,
			final Object[] objs) throws HibernateException;

	/**
	 * 根据hql执行新增、修改或删除操作
	 * 
	 * @param hql
	 * @return
	 * @author yuanjie.wu
	 */
	public int executeUpdate(String hql) throws HibernateException;

	/**
	 * 根据hql设置参数后，执行新增、修改或删除操作 <br>
	 * eg: insert into 对象名称 values(?,...,?); <br>
	 * update from 对象名称 set 对象字段名称1 = ?...对象字段名称n = ? where 对象字段名称1 =
	 * ?...对象字段名称n = ? ; <br>
	 * delete from 对象名称 where 对象字段名称1 = ?...对象字段名称n = ?
	 * 
	 * @param hql
	 *            HQL语句
	 * @param objs
	 *            HQL值数组
	 * @return
	 */
	public int executeUpdate(String hql, Object[] objs)
			throws HibernateException;

	/**
	 * 根据hql设置参数后，执行新增、修改或删除操作 （参数中 params 和 objs 长度必须相同，否则失败返回-1）<br>
	 * eg: insert into 对象名称 values(params[0],...,params[n]); <br>
	 * update from 对象名称 set 对象字段名称1 = :params[0]...对象字段名称n = :params[n] where
	 * 对象字段名称(n+1) = :params[0]...对象字段名称(n+n) = :params[n]; <br>
	 * delete from 对象名称 where 对象字段名称1 = :params[0]...对象字段名称n = :params[n]
	 * 
	 * @param hql
	 *            HQL语句
	 * @param params
	 *            HQL占位符数组
	 * @param objs
	 *            HQL值数组
	 * @return 只有当返回值大于0时操作成功，否则失败
	 * @author yuanjie.wu
	 */
	public int executeUpdate(String hql, String[] params, Object[] objs)
			throws HibernateException;

	/**
	 * 根据sql设置参数后，执行新增、修改或删除操作 <br>
	 * eg: insert into 表名 values(?,...,?); <br>
	 * update from 表名 set 字段名1 = ?...字段名n = ? where 字段名(n+1)= ?...字段名(n+n) = ? ; <br>
	 * delete from 表名 where 对象字段名称1 = ?...对象字段名称n = ?
	 * 
	 * @param sql
	 *            SQL语句
	 * @param objs
	 *            SQL值数组
	 * @return
	 * @author yuanjie.wu
	 */
	public int executeUpdateWithSQL(String sql, Object... objs)
			throws HibernateException;

	/**
	 * 根据sql设置参数后，执行新增、修改或删除操作 （参数中 params 和 objs 长度必须相同，否则失败返回-1）<br>
	 * eg: insert into 表名 values(params[0],...,params[n]); <br/>
	 * update from 表名 set 字段名1 = :params[0]...字段名n = :params[n] where 字段名(n+1) =
	 * :params[0]...字段名(n+n) = :params[n];<br/>
	 * delete from 表名 where 字段名1 =:params[0]...字段名n = :params[n]
	 * 
	 * @param sql
	 *            SQL语句
	 * @param params
	 *            SQL占位符数组
	 * @param objs
	 *            SQL值数组
	 * @return
	 * @author yuanjie.wu
	 */
	public int executeUpdateWithSQL(String sql, String[] params, Object[] objs)
			throws HibernateException;

	/**
	 * 按主键删除数据<br>
	 * eg：delete 对象名 where 对象对应数据库字段的属性名称 in (:ids)
	 * 
	 * @param hql
	 *            HQL语句
	 * @param param
	 *            指定HQL占位字符串
	 * @param ids
	 *            HQL语句值数组
	 * @return
	 * @author yuanjie.wu
	 */
	public int deleteByNamedParam(String hql, String param, Serializable[] value)
			throws HibernateException;

	/**
	 * 按条件删除数据 (参数中 params 与 list 长度必须相同，否则失败返回-1)<br>
	 * eg: delete 对象名称 where 对象对应数据库字段的属性名称1 in (:list.get(0)) and
	 * 对象对应数据库字段的属性名称2 in (:list.get(1))....
	 * 
	 * @param hql
	 *            HQL语句
	 * @param params
	 *            指定HQL占位字符串数组
	 * @param list
	 *            HQL语句值集合数组
	 * @return 只有当返回值大于0时操作成功，否则失败
	 * @author yuanjie.wu
	 */
	public int deleteByNamedParams(String hql, String[] params,
			List<Serializable[]> list) throws HibernateException;

	/**
	 * 执行SQL查询方法
	 * @param <T> (Map, List, javaBean对象)
	 * @param clazz 返回类型
	 * @param sql SQL查询语句
	 * @param values SQL值数组
	 * @return
	 * @throws HibernateException
	 * @author hasee
	 */
	public List<T> queryWithSQL(Class<T> clazz, String sql, Object... values) throws HibernateException;
	
	/**
	 * 分页查询。
	 * @author Chrise 2012-6-7
	 * @param countHql
	 * @param queryHql
	 * @param first
	 * @param max
	 * @return
	 */
	public PageCenterStation<T> queryPage(final String countHql, final String queryHql, final int first, final int max);
	
	/**
	 * 查找唯一对象。
	 * @author Chrise 2012-6-12
	 * @param hql
	 * @return
	 */
	public T findUniqueObject(final String hql);
	
	/**
	 * 查询列表。
	 * @author Chrise 2012-6-15
	 * @param hql
	 * @return
	 */
	public List<T> queryList(final String hql);
	
	/**
	 * 查询列表（元素为MAP对象）。
	 * @author Chrise 2012-6-29
	 * @param hql
	 * @return
	 */
	public List<Map> queryListInMap(final String hql);
	
	/**
	 * 查询记录数。
	 * @author Chrise 2012-6-29
	 * @param sql
	 * @return
	 */
	public long queryCountWithSql(final String sql);
	
	/**
	 * 查询列表。
	 * @author Chrise 2012-6-29
	 * @param sql
	 * @return
	 */
	public List<Object[]> queryListWithSql(final String sql);
	
	/**
	 * 查询列表。
	 * @author Chrise 2012-12-7
	 * @param sql
	 * @param clazz
	 * @return
	 */
	public List<T> queryListWithSql(final String sql, final Class<T> clazz);
	
	/**
	 * 执行sql语句的分页查询方法，返回字段必须与实体字段一一对应。
	 * @author liuzhi Nov 6, 2013
	 * @param clazz
	 * @param countSql
	 * @param sql
	 * @param params
	 * @param objs
	 * @param first
	 * @param max
	 * @return
	 */
	public PageCenterStation<?> queryWithSQL(final Class<T> clazz,
			final String countSql, final String sql, final String[] params,
			final Object[] objs, final int first, final int max);
	
	/**
	 * 执行存储过程查询列表，返回结果转化后的实体
	 * @author Chrise 2012-7-25
	 * @param procedure
	 * @param clazz
	 * @param params
	 * @return
	 */
	public List<T> queryListByProcedure(final String procedure, final Class<T> clazz, final Object... params);
	
	/**
	 * 执行存储过程查询列表，直接返回结果List
	 * @author ls 2013年3月20日 14:22:14
	 * @param procedure
	 * @param params
	 * @return
	 */
	public List<T> queryListByProcedure(final String procedure, final Object... params);
	
	/**
	 * 执行存储过程，无返回值
	 * @author ls 2013年3月20日 14:22:19
	 * @param procedure
	 * @param params
	 */
	public void queryByProcedure(final String procedure, final Object... params);
	
	/**
	 * 执行存储过程，返回整形值
	 * 注意：1、返回的整型值为输出参数，即在MYSQL的存储过程中定义了输出(out)参数。
	 *      2、调用此存储过程(procedure)时必须包含输入参数，即params不能为空。
	 *      3、params中可接受String、Integer、Double、Object类型的参数值。
	 *      
	 * @author liuzhi 2014-2-18
	 * @param procedure 存储过程名称
	 * @param params 参数值列表
	 * @return
	 */
	public int queryProcedureForInt(final String procedure, final Object... params);
}
